#pragma once
/**
 *  页面路由器，控制页面的跳转，生命周期的管理
 */
#include "AppAnim.h"
#include "IPage.h"
#include <vector>
#include <stack>

 /* 路由器所处的环境（状态） */
typedef struct
{
	bool hasSwitchReq;    // 有转场请求
	bool isBusy;          // 正在转场
	bool isEntering;      // 正在进入

	anim_attr_t anim_current;  // 当前动画属性
	anim_attr_t anim_global;   // 全局动画属性

} router_env_t;

class AppRouter {

public:
	virtual ~AppRouter();

	// 应用初始化, 设置通用样式, 注意：要保证在lvgl初始化之后调用
	void AppInit();

	/** 导航-页面跳转 **/
	
	/*
	   @brief  进入新页面, 会销毁当前页
	   @param  param: 传给新页面的参数
	   @retval 是否成功
	*/
	bool GoTo(const char* name, const page_data_t* param); 

	/* 进入下一面，当前页压栈置后，并不销毁，便于返回 */
	bool GoNext(const char* name, const page_data_t* param = nullptr);

	/* 返回上一页，当前页出栈销毁 */
	bool GoBack(const char* name, const page_data_t* param = nullptr);

	/* 返回主页（第一个压栈的页面），其他页面都销毁 */
	bool GoHome();

	// 获取路由单实例
	static AppRouter* GetInstance();

	/* 设置默认的转转场动画 */
	void SetSwitchAnim(anim_type_em type = anim_type_em::LOAD_ANIM_MOVE_LEFT, uint16_t time = 300, lv_anim_path_cb_t path = lv_anim_path_ease_out);
private:
	AppRouter();

	/* 进入新页面, 根据条件是否删除缓存*/
	bool GoPage(const char* name, const page_data_t* param, bool bRemove);

	/* 获取上一个页面名*/
	const char* GetPrevPageName() { return m_pagePrev ? m_pagePrev->m_name : "empty page"; }

	/* 是否有页面在转场中 */
	bool InSwitch();

	/* 保存页面数据 */
	void SavePageParam(IPage* newPage, const page_data_t* param);

	/* 切换页面 */
	bool SwitchTo(IPage* newPage, bool isEnterAct, const page_data_t* param); 

	/* 转场动画开始 */
	void SwitchAnimStart(IPage* base);

	/* 转场是否都结束 */
	bool SwitchReqOver();

	/* 转场动画完成响应 */
	static void OnSwitchAnimFinish(lv_anim_t* anim);

	/* 路由器初始化 */
	void Init();

	/* 强制卸载页面 */
	bool FourceUnload(IPage* page);

	/* 清空页面栈 */
	void ClearStack(bool keepBottom);

	/** 状态机 **/

	/* 页面状态更新 */
	void StateUpdate(IPage* page);

	/* 执行加载状态 */
	page_state_em ExecLoadState(IPage* page);

	/* 执行展示状态 */
	page_state_em ExecWillShowState(IPage* page);
	
	/* 执行展示完成状态 */
	page_state_em ExecShowState(IPage* page);
	
	/* 执行消失状态 */
	page_state_em ExecFinaleState(IPage* page);
	
	/* 执行消失完成状态 */
	page_state_em ExecCloseState(IPage* page);
	
	/* 执行页面卸载状态 */
	page_state_em ExecUnloadState(IPage* page);


	/** 动画 **/

	/* 更新页面转场动画属性 */
	void SwitchAnimTypeUpdate(IPage* page);

	/* 获取加载动画 */ 
	bool GetLoadAnimAttr(anim_type_em type, page_anim_attr_t* attr);
	
	/* 是否Over类型动画 */
	bool IsOverAnim(anim_type_em type){ return (type >= anim_type_em::LOAD_ANIM_OVER_LEFT && type <= anim_type_em::LOAD_ANIM_OVER_BOTTOM); }

	/* 是否Move类型动画 */
	bool IsMoveAnim(anim_type_em type){ return (type >= anim_type_em::LOAD_ANIM_MOVE_LEFT && type <= anim_type_em::LOAD_ANIM_MOVE_BOTTOM); }
	
	/* 初始化动画 */
	void AnimInit(lv_anim_t* a);
	
	/* 获取当前加载动画 */
	bool GetCurrentLoadAnimAttr(page_anim_attr_t* attr){ return GetLoadAnimAttr(m_env.anim_current.type, attr); }

	/** 屏幕 **/

	IPage* m_pagePrev;                // 前一页
	IPage* m_pageCur;                 // 当前页
	lv_style_t m_body_style;          // 默认样式
	router_env_t m_env;               // 路由器状态 
};

